#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sip, string
from PyQt4 import QtCore, QtGui
from dialog_new_acquisition import *
from Ui_dialog_new_acquisition import *
from time import strftime
from libASFX import *


class dialog_new_acquisition( QtGui.QDialog, Ui_Dialog_new_acquisition):
	"""Describe the new acquisition dialog"""

	def __init__( self, window_parent, libmyCF):
		super( dialog_new_acquisition, self).__init__( window_parent)
		self.setupUi( self)
		self.parent=window_parent
		self.libmyCF = libmyCF
		
		self.groupBoxes = [] # Used to delete QT widgets when the organ is changed
		self.widgetContainer = [] # Used to register new objects
		
		for ae in self.libmyCF.ontology.all_AEs.values():
			self.comboBox_organ.addItem( QtCore.QString.fromUtf8( ae.getName()))
		for type in ["MRI", "Scanner"]:
			self.comboBox_type.addItem( QtCore.QString.fromUtf8( type))


	@QtCore.pyqtSignature( "const QString&")
	def on_comboBox_organ_currentIndexChanged( self, label):
		#print "organ changed to %s"%( label)
		isARel = self.libmyCF.ontology.getRelationTypeNamed( "is_a")
		
		# Get the AEs tagged bu the attribute type 'base_type_of_new_acquisition'
		attributes = self.libmyCF.ontology.getAttributesNamed( "base_type_of_new_acquisition")
		attributesNamesList = [] # It contains all interesting AE name (bones, ligaments, etc)
		for att in attributes:
			attributesNamesList.append( att.getAE().getName())
		
		# Get all the AEs contained in the selected organ
		organ = self.libmyCF.ontology.getAENamed( label)
		containedAEs = self.libmyCF.ontology.getAEsPartOf( organ)
		
		# Initialisation of an instances container
		instancesContainer = {}
		for att in attributesNamesList:
			instancesContainer[ att ] = []
		instancesContainer["Other"] = []
		
		# Sort the different instances depending of the base types
		for ae in containedAEs:
			baseType = ae.isA( attributesNamesList)
			if( baseType == ""): instancesContainer["Other"].append( ae)
			else: instancesContainer[ baseType ].append( ae)
		
		# Destroy existing layout
		oldLayout = self.scrollAreaWidgetContents.layout()
		if isinstance( oldLayout, QtGui.QVBoxLayout):
			for widget in self.groupBoxes:
				oldLayout.removeWidget( widget)
				widget.setParent( None)
				sip.delete( widget)
			self.groupBoxes = []
			self.widgetContainer = []
			sip.delete( oldLayout)
		# Create a new layout
		vertLayout = QtGui.QVBoxLayout( self.scrollAreaWidgetContents)
		self.scrollAreaWidgetContents.setLayout( vertLayout)
		vertLayout.setObjectName("vertLayout")
		
		# Add the widgets depending on the container content
		widgetsGroupBox = []
		for key, instances in instancesContainer.items():
			if len( instances) == 0: continue
			# Create a label and a grid layout
			groupBox = QtGui.QGroupBox( QtCore.QString.fromUtf8( key ), self.scrollAreaWidgetContents)
			groupBox.setObjectName("groupBox_" + key)
			self.groupBoxes.append( groupBox)
			vertLayout.addWidget( groupBox)
			gridLayout = QtGui.QGridLayout( groupBox)
			
			row = 0
			column = 0
#			widgetsRow = []
			for ae in instances: # = sections (ex: bones, ligaments, insertions...)
				if len( ae.get_l_child( isARel.getId())) != 0: continue
				
				attributes = ae.getAttributes()
				if len( attributes) == 0: continue
				
				column = 0
				#print str(key) + ": " + ae.getName()
				gridLayout.addWidget( QtGui.QLabel( QtCore.QString.fromUtf8( ae.getName())), row, column )
				column = column + 1
				
#				widgetsColumn = []
				# Add all the widget depending of the attribute value type
				for att in attributes:
					widget = self.createValueWidget( groupBox, ae, att)
					gridLayout.addWidget( widget, row, column )
#					widgetsColumn.append( [ False, att, widget])
					
					column = column + 1
				# Add a spacer to keep compact options inside each groupBox
				gridLayout.addItem( QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.MinimumExpanding), row, column)
#				widgetsRow.append( widgetsColumn)
				row = row + 1
#			widgetsGroupBox.append( widgetsRow)
		
#		self.widgetContainer.append( widgetsGroupBox)
		
		# Add a spacer in case of short list
		vertLayout.addItem( QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding))


	def accept( self):
		# Do stuff here (myCF registration)
		self.registerAcquisition()
		QtGui.QDialog.accept( self)


	def createLabel( self, name, width):
		label = QtGui.QLabel( QtCore.QString.fromUtf8( name))
		#label.setWordWrap( True)
		#label.setMaximumWidth( width)
		#label.sizePolicy().setHorizontalPolicy( QtGui.QSizePolicy.Fixed)
		return label


	def createValueWidget( self, parent, ae, attribute):
		"""Create a widget depending of the type of the attribute"""
		cellWidth = 180
		
		widget = QtGui.QWidget( parent)
		gridLayout = QtGui.QGridLayout( widget)
		type = attribute.getType()
		
		if type == "boolean":
			# create a check box
			label = self.createLabel( attribute.getName(), cellWidth/2.0)
			gridLayout.addWidget( label, 0, 0, 1, -1)
			w = QtGui.QCheckBox( QtCore.QString(), widget)
			w.setMaximumWidth( cellWidth/2.0)
			w.setToolTip( QtCore.QString.fromUtf8( attribute.getDefinition()))
			self.connect( w, QtCore.SIGNAL("stateChanged( int)"),self.widgetModified)
			gridLayout.addWidget( w)
			self.widgetContainer.append( [ id( w), w, ae, attribute, False ])
		
		elif type == "float":
			# create a lineEdit
			label = self.createLabel( attribute.getName(), cellWidth/2.0)
			gridLayout.addWidget( label, 0, 0, 1, -1)
			w = QtGui.QLineEdit( QtCore.QString.fromUtf8( attribute.getValue()), widget)
			w.setMinimumWidth( cellWidth/2.0)
			w.setMaximumWidth( cellWidth/2.0)
			w.setSizePolicy( QtGui.QSizePolicy( QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed))
			w.setToolTip( QtCore.QString.fromUtf8( attribute.getDefinition()))
			self.connect( w, QtCore.SIGNAL("textChanged( const QString&)"),self.widgetModified)
			gridLayout.addWidget( w, 1, 0)
			self.widgetContainer.append( [ id( w), w, ae, attribute, False ])
		
		elif type == "3*float":
			# create three lineEdit
			label = self.createLabel( attribute.getName(), cellWidth)
			gridLayout.addWidget( label, 0, 0, 1, -1)
			value = string.split( attribute.getValue(), " ")
			for i in range( 3):
				w = QtGui.QLineEdit( QtCore.QString.fromUtf8( value[i]), widget)
				w.setMinimumWidth( cellWidth/3)
				w.setMaximumWidth( cellWidth/3)
				w.setSizePolicy( QtGui.QSizePolicy( QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed))
				w.setToolTip( QtCore.QString.fromUtf8( attribute.getDefinition()))
				self.connect( w, QtCore.SIGNAL("textChanged( const QString&)"),self.widgetModified)
				gridLayout.addWidget( w, 1, i)
				self.widgetContainer.append( [ id( w), w, ae, attribute, False ])
		
		elif type == "9*float":
			# create nine lineEdit
			label = self.createLabel( attribute.getName(), cellWidth)
			gridLayout.addWidget( label, 0, 0, 1, -1)
			value = string.split( attribute.getValue(), " ")
			for i in range( 3):
				for j in range( 3):
					w = QtGui.QLineEdit( QtCore.QString.fromUtf8( value[3*i+j]), widget)
					w.setMinimumWidth( cellWidth/3)
					w.setMaximumWidth( cellWidth/3)
					w.setSizePolicy( QtGui.QSizePolicy( QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed))
					w.setToolTip( QtCore.QString.fromUtf8( attribute.getDefinition()))
					self.connect( w, QtCore.SIGNAL("textChanged( const QString&)"),self.widgetModified)
					gridLayout.addWidget( w, i+1, j)
					self.widgetContainer.append( [ id( w), w, ae, attribute, False ])
		
		elif type == "text":
			# create a lineEdit
			label = self.createLabel( attribute.getName(), cellWidth)
			gridLayout.addWidget( label, 0, 0, 1, -1)
			w = QtGui.QLineEdit( QtCore.QString.fromUtf8( attribute.getValue()), widget)
			w.setMinimumWidth( cellWidth)
			w.setMaximumWidth( cellWidth)
			w.setSizePolicy( QtGui.QSizePolicy( QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed))
			w.setToolTip( QtCore.QString.fromUtf8( attribute.getDefinition()))
			self.connect( w, QtCore.SIGNAL("textChanged( const QString&)"),self.widgetModified)
			gridLayout.addWidget( w, 1, 0)
			self.widgetContainer.append( [ id( w), w, ae, attribute, False ])
		
		else:
			gridLayout.addWidget( QtGui.QLabel( QtCore.QString.fromUtf8( "Error: Type\nd'attribut\n\"%s\"\ninconnu !"%( type)), widget), 0, 0)
		
		#TODO: add widget into an array to update args then on the database
		return widget


	def widgetModified( self):
		widget = self.sender()
		
		for tuple in self.widgetContainer:
			if tuple[0] == id(widget):
				tuple[4] = True
				break


	def registerAcquisition( self):
		"""Parse the container and register the modified elements into the database"""
		print "Acquisitions registration done (but not all inside it)."
		
		organId = self.libmyCF.ontology.getAENamed( self.comboBox_organ.currentText().toUtf8()).getId()
		type = self.comboBox_type.currentText().toUtf8()
		date = strftime("%Y-%m-%d")
		team = self.lineEdit_team.text().toUtf8()
		comment = self.textEdit_comment.toPlainText().toUtf8()
		
		#if( check each args TODO...
		
		newAcq = self.libmyCF.acquisitions.addAcquisition( Acquisition( self.libmyCF, None, organId, type, date, team, comment))
		
		for tuple in self.widgetContainer:
			widgetId = tuple[0]
			widget = tuple[1]
			ae = tuple[2]
			att = tuple[3]
			widgetModified = tuple[4]
			
			if widgetModified: # If the widget value has been modified
				instance = newAcq.getInstanceOfAE( ae) # Create the instance if there is no one
				instAtt = instance.getAttributesNamed( att.getName())[0] # Create the attribute if there is no one
				self.registerInstanceDependingOnType( instAtt, widget, ae)
		return


	def registerInstanceDependingOnType( self, instAtt, widget, ae):
		attType = instAtt.getType()
		if attType == "boolean": # CheckBox case
			print "boolean"
			if widget.isChecked():
				value = "1"
			else:
				value = "0"
		elif attType == "float" or attType == "text": # LineEdit case
			value = widget.text().toUtf8()
		elif attType == "3*float" or attType == "9*float": # Multiple LineEdit case
			layout = widget.parentWidget().layout()
			value = ""
			for i in range( layout.count()):
				w = layout.itemAt( i).widget()
				if isinstance( w, QtGui.QLineEdit):
					value += w.text().toUtf8() + " "
		else:
			print "Unknown attribute type to register"
		instAtt.update( value) # depend du type !
